home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Graphics⁄Sound / Fudd Source / Fudd ƒ / MSG Shell ƒ / msg graphics.c < prev    next >
Text File  |  1994-02-07  |  12KB  |  468 lines

  1. /**********************************************************************\
  2.  
  3. File:        msg graphics.c
  4.  
  5. Purpose:    This module handles opening/closing/updating all windows:
  6.             help window and about windows.  This includes
  7.             manipulating offscreen bitmaps for fun and no profit.
  8.  
  9.  
  10. Fudd -=- convert text to Elmer Fudd talk
  11. Copyright ©1994, Mark Pilgrim
  12.  
  13. This program is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 2 of the License, or
  16. (at your option) any later version.
  17.  
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with this program in a file named "GNU General Public License".
  25. If not, write to the Free Software Foundation, 675 Mass Ave,
  26. Cambridge, MA 02139, USA.
  27.  
  28. \**********************************************************************/
  29.  
  30. #include "msg graphics.h"
  31. #include "msg about.h"
  32. #include "msg help.h"
  33. #include "msg dialogs.h"
  34. #include "msg error.h"
  35. #include "msg menus.h"
  36. #include "msg environment.h"
  37. #include "msg prefs.h"
  38. #include "program globals.h"
  39. #include "fudd.h"
  40.  
  41. Boolean            gInitedWindowBounds[NUM_WINDOWS];
  42. Rect            gMainScreenBounds;
  43. Rect            gWindowBounds[NUM_WINDOWS];
  44. GDHandle        gBiggestDevice;
  45. WindowPtr        gTheWindow[NUM_WINDOWS];
  46. int                gWindowWidth[NUM_WINDOWS];
  47. int                gWindowHeight[NUM_WINDOWS];
  48. Str255            gWindowTitle[NUM_WINDOWS];
  49. int                gWindowType[NUM_WINDOWS];
  50. Boolean            gOffscreenNeedsUpdate[NUM_WINDOWS];
  51. int                gNumHelp;
  52.  
  53. /* internal stuff */
  54. Rect            bRect[NUM_WINDOWS];
  55. Ptr                myBits[NUM_WINDOWS];
  56. CGrafPort        myCGrafPort[NUM_WINDOWS];
  57. CGrafPtr        myCGrafPtr[NUM_WINDOWS];
  58. CTabHandle        ourCMHandle[NUM_WINDOWS];
  59. GrafPort        myGrafPort[NUM_WINDOWS];
  60. GrafPtr            myGrafPtr[NUM_WINDOWS];
  61. int                gLastDepth[NUM_WINDOWS];
  62. int                gMaxDepth[NUM_WINDOWS];
  63.  
  64. void InitMSGGraphics(void)
  65. {
  66.     int                i;
  67.     
  68.     gAboutColorPict=gAboutBWPict=0L;
  69.     
  70.     gWindowWidth[kAbout]=180;
  71.     gWindowHeight[kAbout]=250;
  72.     
  73.     gWindowWidth[kAboutMSG]=243;
  74.     gWindowHeight[kAboutMSG]=243;
  75.     
  76.     gWindowWidth[kHelp]=300;
  77.     gWindowHeight[kHelp]=250;
  78.     
  79.     for (i=0; i<NUM_WINDOWS; i++)
  80.     {
  81.         myCGrafPtr[i]=myGrafPtr[i]=gTheWindow[i]=0L;
  82.         gInitedWindowBounds[i]=FALSE;
  83.         gOffscreenNeedsUpdate[i]=TRUE;
  84.     }
  85.     
  86.     gMaxDepth[kAbout]=8;
  87.     gMaxDepth[kAboutMSG]=1;
  88.     gMaxDepth[kHelp]=1;
  89.     
  90.     gWindowType[kAbout]=altDBoxProc;
  91.     gWindowType[kAboutMSG]=plainDBox;
  92.     gWindowType[kHelp]=noGrowDocProc;
  93.     
  94.     StuffHex(gWindowTitle[kHelp], "\p0448656c70");
  95.     gWindowTitle[kAbout][0]=gWindowTitle[kAboutMSG][0]==0x00;
  96. }
  97.  
  98. void OpenTheWindow(int index)
  99. {
  100.     unsigned long        dummy;
  101.     
  102.     if (!gTheWindow[index])
  103.     {
  104.         if (!gInitedWindowBounds[index])
  105.         {
  106.             if (index==kHelp)
  107.             {
  108.                 gWindowBounds[index].left=10;
  109.                 gWindowBounds[index].top=50;
  110.             }
  111.             else
  112.             {
  113.                 gWindowBounds[index].left = gMainScreenBounds.left + (((gMainScreenBounds.right -
  114.                             gMainScreenBounds.left) - gWindowWidth[index]) / 2);
  115.                 gWindowBounds[index].top = 9+ gMainScreenBounds.top + (((gMainScreenBounds.bottom -
  116.                             gMainScreenBounds.top) - gWindowHeight[index]) / 2);
  117.             }
  118.             if(gWindowBounds[index].top < 30)
  119.                 gWindowBounds[index].top = 30;
  120.             gWindowBounds[index].bottom = gWindowBounds[index].top + gWindowHeight[index];
  121.             gWindowBounds[index].right = gWindowBounds[index].left + gWindowWidth[index];
  122.             gInitedWindowBounds[index]=TRUE;
  123.         }
  124.         
  125.         if(gHasColorQD)
  126.         {
  127.             gTheWindow[index] = NewCWindow(0L, &gWindowBounds[index], gWindowTitle[index],
  128.                 TRUE, gWindowType[index], (WindowPtr)-1L, TRUE, 0L);
  129.         }
  130.         else
  131.         {
  132.             gTheWindow[index] = NewWindow(0L, &gWindowBounds[index], gWindowTitle[index],
  133.                 TRUE, gWindowType[index], (WindowPtr)-1L, TRUE, 0L);
  134.         }
  135.  
  136.         bRect[index] = gTheWindow[index]->portRect;
  137.     }
  138.     
  139.     if (gTheWindow[index])
  140.     {
  141.         SelectWindow(gTheWindow[index]);
  142.         SetPort(gTheWindow[index]);
  143.         UpdateTheWindow(index);
  144.         if (index==kAboutMSG)
  145.             Delay(30, &dummy);
  146.     }
  147.     else ErrorString("\pThere is not enough memory to open the window.","\p");
  148. }
  149.  
  150. void GetMainScreenBounds(void)
  151. {
  152.     gMainScreenBounds = screenBits.bounds;
  153.     gMainScreenBounds.top += MBarHeight;
  154. }
  155.  
  156. int GetWindowDepth(int index)
  157. {
  158.     Rect        tempRect;
  159.     long        biggestSize;
  160.     long        tempSize;
  161.     GDHandle    thisHandle;
  162.     
  163.     if (gHasColorQD)
  164.     {
  165.         if (gTheWindow[index])
  166.         {
  167.             thisHandle = GetDeviceList();
  168.             gBiggestDevice = 0L;
  169.             biggestSize = 0L;
  170.             
  171.             while (thisHandle)
  172.             {
  173.                 if (TestDeviceAttribute(thisHandle, screenDevice) &&
  174.                             TestDeviceAttribute(thisHandle, screenActive))
  175.                     if (SectRect(&(gTheWindow[index]->portRect), &((**thisHandle).gdRect),
  176.                                 &tempRect))
  177.                         if (biggestSize < (tempSize =
  178.                                 ((long)(tempRect.bottom - tempRect.top))
  179.                                 * ((long)(tempRect.right - tempRect.left))))
  180.                         {
  181.                             biggestSize = tempSize;
  182.                             gBiggestDevice = thisHandle;
  183.                         }
  184.                 thisHandle = GetNextDevice(thisHandle);
  185.             }
  186.             
  187.             if (gBiggestDevice)
  188.                 return (**(**gBiggestDevice).gdPMap).pixelSize;
  189.             else
  190.                 return 1;
  191.         }
  192.         else
  193.         {
  194.             return (**(**GetMainDevice()).gdPMap).pixelSize;
  195.         }
  196.     }
  197.     else
  198.     {
  199.         return 1;
  200.     }
  201. }
  202.  
  203. void UpdateTheWindow(int index)
  204. {
  205.     long        offRowBytes, sizeOfOff;
  206.     int            theDepth, i, err;
  207.     GDHandle    oldDevice;
  208.  
  209.     if (((theDepth = GetWindowDepth(index)) > 2) && (gMaxDepth[index]>2))
  210.     {
  211.         /* if we just changed from one color depth to another color depth */
  212.         if((myCGrafPtr[index] != 0L) && (gLastDepth[index] != theDepth))
  213.         {
  214.             DisposeHandle((**(myCGrafPort[index]).portPixMap).pmTable);
  215.             DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  216.             CloseCPort(myCGrafPtr[index]);
  217.             myCGrafPtr[index] = 0L;            
  218.             gOffscreenNeedsUpdate[index]=TRUE;
  219.         }
  220.         
  221.         if (myCGrafPtr[index]==0L)
  222.         {
  223.             /* if we just switched from b/w to color, delete the b/w port */
  224.             if(myGrafPtr[index] != 0L)
  225.             {
  226.                 DisposePtr(myGrafPort[index].portBits.baseAddr);
  227.                 ClosePort(myGrafPtr[index]);
  228.                 myGrafPtr[index] = 0L;
  229.                 gOffscreenNeedsUpdate[index]=TRUE;
  230.             }
  231.             
  232.             if (gBiggestDevice)
  233.             {
  234.                 oldDevice = GetGDevice();
  235.                 SetGDevice(gBiggestDevice);
  236.             }
  237.             else
  238.                 oldDevice = 0L;
  239.             
  240.             myCGrafPtr[index] = &myCGrafPort[index];
  241.             OpenCPort(myCGrafPtr[index]);
  242.             gLastDepth[index] = theDepth = (**(myCGrafPort[index]).portPixMap).pixelSize;
  243.             if (theDepth>gMaxDepth[index])
  244.                 gLastDepth[index]=theDepth=gMaxDepth[index];
  245.             
  246.             offRowBytes = (((theDepth * (bRect[index].right - bRect[index].left)) + 15) >> 4) << 1;
  247.             sizeOfOff = (long)(bRect[index].bottom - bRect[index].top) * offRowBytes;
  248.             OffsetRect(&bRect[index], -bRect[index].left, -bRect[index].top);
  249.             
  250.             myBits[index] = NewPtr(sizeOfOff);
  251.             if(myBits[index] == 0L)
  252.             {
  253.                 CloseCPort(myCGrafPtr[index]);
  254.                 myCGrafPtr[index]=0L;
  255.                 ErrorString("\pThere is not enough memory to open the window.","\p");
  256.             }
  257.             
  258.             (**(myCGrafPort[index]).portPixMap).baseAddr = myBits[index];
  259.             (**(myCGrafPort[index]).portPixMap).rowBytes = offRowBytes + 0x8000;
  260.             (**(myCGrafPort[index]).portPixMap).bounds = bRect[index];
  261.             
  262.             myCGrafPort[index].portRect = bRect[index];
  263.             
  264.             ourCMHandle[index] = (**(**gBiggestDevice).gdPMap).pmTable;
  265.             err = HandToHand(&ourCMHandle[index]);
  266.             if(err != noErr)
  267.             {
  268.                 DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  269.                 CloseCPort(myCGrafPtr[index]);
  270.                 myCGrafPtr[index]=0L;
  271.                 ErrorString("\pThere is not enough memory to open the window.","\p");
  272.             }
  273.             
  274.             for(i = 0; i <= (**ourCMHandle[index]).ctSize; i++)
  275.                 (**ourCMHandle[index]).ctTable[i].value = i;
  276.             (**ourCMHandle[index]).ctFlags &= 0x7fff;
  277.             (**ourCMHandle[index]).ctSeed = GetCTSeed();
  278.             
  279.             (**(myCGrafPort[index]).portPixMap).pmTable = ourCMHandle[index];
  280.             
  281.             if (oldDevice)
  282.                 SetGDevice(oldDevice);
  283.         }
  284.         
  285.         UpdateTheWindowColor(index);
  286.     }
  287.     else
  288.     {
  289.         if (myGrafPtr[index]==0L)
  290.         {
  291.             if(myCGrafPtr[index] != 0L)
  292.             {
  293.                 DisposeHandle((**(myCGrafPort[index]).portPixMap).pmTable);
  294.                 DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  295.                 CloseCPort(myCGrafPtr[index]);
  296.                 myCGrafPtr[index] = 0L;
  297.                 gOffscreenNeedsUpdate[index]=TRUE;
  298.             }
  299.             
  300.             myGrafPtr[index] = &myGrafPort[index];
  301.             OpenPort(myGrafPtr[index]);
  302.             
  303.             offRowBytes = (((bRect[index].right - bRect[index].left) + 15) >> 4) << 1;
  304.             sizeOfOff = (long)(bRect[index].bottom - bRect[index].top) * offRowBytes;
  305.             OffsetRect(&bRect[index], -bRect[index].left, -bRect[index].top);
  306.             
  307.             myBits[index] = NewPtr(sizeOfOff);
  308.             if(myBits[index] == 0L)
  309.             {
  310.                 ClosePort(myGrafPtr[index]);
  311.                 myGrafPtr[index]=0L;
  312.                 ErrorString("\pThere is not enough memory to open the window.", "\p");
  313.             }
  314.             
  315.             myGrafPort[index].portBits.baseAddr = myBits[index];
  316.             myGrafPort[index].portBits.rowBytes = offRowBytes;
  317.             myGrafPort[index].portBits.bounds = bRect[index];
  318.             myGrafPort[index].portRect = bRect[index];            
  319.         }
  320.         
  321.         UpdateTheWindowBW(index);
  322.     }
  323.     
  324.     ValidRect(&(gTheWindow[index]->portRect));
  325. }
  326.  
  327. void UpdateTheWindowColor(int index)
  328. {
  329.     GDHandle    oldDevice;
  330.     RgnHandle    oldClipRgn;
  331.     RgnHandle    newClipRgn;
  332.     
  333.     if (gOffscreenNeedsUpdate[index])
  334.     {
  335.         oldDevice = GetGDevice();
  336.         SetGDevice(gBiggestDevice);
  337.         oldClipRgn = myCGrafPort[index].clipRgn;
  338.         newClipRgn=NewRgn();
  339.         SetRectRgn(newClipRgn, 0, 0, gWindowWidth[index], gWindowHeight[index]);
  340.         
  341.         myCGrafPort[index].clipRgn=newClipRgn;
  342.             
  343.         SetPort((GrafPtr)myCGrafPtr[index]);
  344.         
  345.         switch (index)
  346.         {
  347.             case kAbout:
  348.                 DrawTheAboutBox(TRUE);
  349.                 break;
  350.             case kAboutMSG:
  351.                 DrawTheCarpet();
  352.                 break;
  353.             case kHelp:
  354.                 DrawTheHelp(TRUE);
  355.                 break;
  356.         }
  357.         SetGDevice(oldDevice);
  358.         myCGrafPort[index].clipRgn = oldClipRgn;
  359.         DisposeRgn(newClipRgn);
  360.         gOffscreenNeedsUpdate[index]=FALSE;
  361.     }
  362.     
  363.     SetPort(gTheWindow[index]);
  364.     
  365.     CopyBits(&(((GrafPtr)myCGrafPtr[index])->portBits),
  366.                 &(gTheWindow[index]->portBits), &bRect[index], &bRect[index], 0, 0L);
  367. }
  368.  
  369. void UpdateTheWindowBW(int index)
  370. {
  371.     RgnHandle    oldClipRgn;
  372.     RgnHandle    newClipRgn;
  373.     
  374.     if (gOffscreenNeedsUpdate[index])
  375.     {
  376.         oldClipRgn = myGrafPort[index].clipRgn;
  377.         newClipRgn=NewRgn();
  378.         SetRectRgn(newClipRgn, 0, 0, gWindowWidth[index], gWindowHeight[index]);
  379.         myCGrafPort[index].clipRgn=newClipRgn;
  380.         SetPort(myGrafPtr[index]);
  381.         switch (index)
  382.         {
  383.             case kAbout:
  384.                 DrawTheAboutBox(FALSE);
  385.                 break;
  386.             case kAboutMSG:
  387.                 DrawTheCarpet();
  388.                 break;
  389.             case kHelp:
  390.                 DrawTheHelp(FALSE);
  391.                 break;
  392.         }
  393.         myGrafPort[index].clipRgn = oldClipRgn;
  394.         DisposeRgn(newClipRgn);
  395.         gOffscreenNeedsUpdate[index]=FALSE;
  396.     }
  397.     
  398.     SetPort(gTheWindow[index]);
  399.     
  400.     CopyBits(&(myGrafPtr[index]->portBits),
  401.                 &(gTheWindow[index]->portBits), &bRect[index], &bRect[index], 0, 0L);
  402. }
  403.  
  404. void UpdateHelpWindow(void)
  405. {
  406.     gOffscreenNeedsUpdate[kHelp]=TRUE;
  407.     OpenTheWindow(kHelp);
  408. }
  409.  
  410. void CloseTheWindow(int index)
  411. {
  412.     DisposeWindow(gTheWindow[index]);
  413.     gTheWindow[index]=0L;
  414.     
  415.     if (index==kHelp)
  416.         gOffscreenNeedsUpdate[kHelp]=TRUE;
  417. }
  418.  
  419. void DrawThePicture(PicHandle *thePict, int whichPict, int x, int y)
  420. {
  421.     Rect            temp;
  422.     
  423.     if (*thePict==0L)
  424.         *thePict=(PicHandle)GetPicture(whichPict);
  425.     
  426.     HLock(*thePict);
  427.     temp.top=y;
  428.     temp.left=x;
  429.     temp.bottom=temp.top+(***thePict).picFrame.bottom-(***thePict).picFrame.top;
  430.     temp.right=temp.left+(***thePict).picFrame.right-(***thePict).picFrame.left;
  431.     DrawPicture(*thePict, &temp);
  432.     HUnlock(*thePict);
  433. }
  434.  
  435. void ReleaseThePict(PicHandle *thePict)
  436. {
  437.     if (*thePict!=0L)
  438.     {
  439.         ReleaseResource(*thePict);
  440.         *thePict=0L;
  441.     }
  442. }
  443.  
  444. void ShutDownMSGGraphics(void)
  445. {
  446.     int                i;
  447.     
  448.     ReleaseThePict(gAboutColorPict);
  449.     ReleaseThePict(gAboutBWPict);
  450.     
  451.     for (i=0; i<NUM_WINDOWS; i++)
  452.     {
  453.         if ((myCGrafPtr[i]!=0L) || (myGrafPtr[i]!=0L))
  454.             DisposPtr(myBits[i]);
  455.         if(myCGrafPtr[i] != 0L)
  456.         {
  457.             DisposeHandle((**(myCGrafPort[i]).portPixMap).pmTable);
  458.             CloseCPort(myCGrafPtr[i]);
  459.             myCGrafPtr[i] = 0L;
  460.         }
  461.         if(myGrafPtr[i] != 0L)
  462.         {
  463.             ClosePort(myGrafPtr[i]);
  464.             myGrafPtr[i] = 0L;
  465.         }
  466.     }
  467. }
  468.